package com.example.apigateway.swagger;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/** @author yang */
@Slf4j
@Component
@Primary
@AllArgsConstructor
public class SwaggerProvider implements SwaggerResourcesProvider {

  public static final String API_URI = "/v2/api-docs";
  /** 网关路由 */
  private final RouteLocator routeLocator;

  private final GatewayProperties gatewayProperties;

  /** 网关应用名称 */
  @Value("${spring.application.name}")
  private String self;

  @Autowired
  public SwaggerProvider(RouteLocator routeLocator, GatewayProperties gatewayProperties) {
    this.routeLocator = routeLocator;
    this.gatewayProperties = gatewayProperties;
  }

  @Override
  public List<SwaggerResource> get() {
    List<SwaggerResource> resources = new ArrayList<>();
    List<String> routeHosts = new ArrayList<>();
    // 由于我的网关采用的是负载均衡的方式，因此我需要拿到所有应用的serviceId
    // 获取所有可用的host：serviceId
    routeLocator
        .getRoutes()
        .filter(route -> route.getUri().getHost() != null)
        .filter(route -> !self.equals(route.getUri().getHost()))
        .subscribe(route -> routeHosts.add(route.getUri().getHost()));

    // 记录已经添加过的server，存在同一个应用注册了多个服务在nacos上
    Set<String> dealed = new HashSet<>();
    routeHosts.forEach(
        instance -> {
          // 拼接url，样式为/serviceId/v2/api-info，当网关调用这个接口时，会自动通过负载均衡寻找对应的主机
          String url = "/" + instance + API_URI;
          if (!dealed.contains(url)) {
            dealed.add(url);
            resources.add(swaggerResource(url, instance+ API_URI));
          }
        });
    return resources;
  }

  // @Override
  // public List<SwaggerResource> get() {
  //   List<SwaggerResource> resources = new ArrayList<>();
  //   List<String> routes = new ArrayList<>();
  //   // 取出 Spring Cloud Gateway 中的 route
  //   routeLocator
  //       .getRoutes() //
  //       .subscribe(route -> routes.add(route.getId()));
  //   // 结合 application.yml 中的路由配置, 只获取有效的 route 节点
  //   gatewayProperties.getRoutes().stream() //
  //       .filter(routeDefinition -> routes.contains(routeDefinition.getId()))
  //       .forEach(
  //           routeDefinition ->
  //               routeDefinition.getPredicates().stream()
  //                   .filter(
  //                       predicateDefinition ->
  //                           "Path".equalsIgnoreCase(predicateDefinition.getName().toLowerCase()))
  //                   .forEach(
  //                       predicateDefinition ->
  //                           resources.add(
  //                               swaggerResource(
  //                                   routeDefinition.getId(),
  //                                   predicateDefinition
  //                                       .getArgs()
  //                                       .get(NameUtils.GENERATED_NAME_PREFIX + "0")
  //                                       .replace("/**", API_URI)))));
  //   return resources;
  // }

  private SwaggerResource swaggerResource(String name, String instance) {
    SwaggerResource swaggerResource = new SwaggerResource();
    swaggerResource.setName(name);
    swaggerResource.setLocation("/"+instance);
    swaggerResource.setSwaggerVersion("2.0");
    return swaggerResource;
  }
}
